<html>
  <head>
	  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>README</title>
		<link href="toc/style/github-bf51422f4bb36427d391e4b75a1daa083c2d840e.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/style/github2-d731afd4f624c99a4b19ad69f3083cd6d02b81d5.css" media="all" rel="stylesheet" type="text/css"/>
		<link href="toc/css/zTreeStyle/zTreeStyle.css" media="all" rel="stylesheet" type="text/css"/>
	  <style>
		pre {
		    counter-reset: line-numbering;
		    border: solid 1px #d9d9d9;
		    border-radius: 0;
		    background: #fff;
		    padding: 0;
		    line-height: 23px;
		    margin-bottom: 30px;
		    white-space: pre;
		    overflow-x: auto;
		    word-break: inherit;
		    word-wrap: inherit;
		}

		pre a::before {
		  content: counter(line-numbering);
		  counter-increment: line-numbering;
		  padding-right: 1em; /* space after numbers */
		  width: 25px;
		  text-align: right;
		  opacity: 0.7;
		  display: inline-block;
		  color: #aaa;
		  background: #eee;
		  margin-right: 16px;
		  padding: 2px 10px;
		  font-size: 13px;
		  -webkit-touch-callout: none;
		  -webkit-user-select: none;
		  -khtml-user-select: none;
		  -moz-user-select: none;
		  -ms-user-select: none;
		  user-select: none;
		}

		pre a:first-of-type::before {
		  padding-top: 10px;
		}

		pre a:last-of-type::before {
		  padding-bottom: 10px;
		}

		pre a:only-of-type::before {
		  padding: 10px;
		}

		.highlight { background-color: #ffffcc } /* RIGHT */
		</style>
  </head>
  <body>
	  <div>
				<div style='width:25%;'>
						<ul id="tree" class="ztree" style='width:100%'>

						</ul>
				</div>
        <div id='readme' style='width:70%;margin-left:20%;'>
          	<article class='markdown-body'>
            	<h1 id="-">一般性原则</h1>
<h2 id="-">文件命名</h2>
<p>所有的文件名应该都遵循同一命名约定。应使用减号（-）是用来分隔文件名，URL也是，例如big-black-background.jpg ，example.com/blog/my-blog-entry。</p>
<p>请确保文件命名总是以字母开头而不是数字获取其他字符。</p>
<p>资源的字母名称必须全为小写，这是因为在某些对大小写字母敏感的操作系统中，当文件通过工具压缩混淆后，或者人为修改过后，大小写不同而导致引用文件不同的错误，很难被发现。</p>
<p>还有一些情况下，需要对文件增加前后缀或特定的扩展名（比如 .min.js, .min.css），抑或一串前缀（比如 3fa89b.main.min.css）。这种情况下，建议使用点分隔符来区分这些在文件名中带有清晰意义的元数据。</p>
<h2 id="-">协议</h2>
<p>不要指定引入资源所带的具体协议。</p>
<p>当引入图片或其他资源文件，还有样式和脚本时，URLs 所指向的具体路径，不要指定协议部分（http:, https:），除非必须指明协议才能使用资源。例如：</p>
<p>不推荐：</p>
<pre><code>//bad
&lt;script src=&quot;http://cdn.com/foundation.min.js&quot;&gt;&lt;/script&gt;

//good 推荐
&lt;script src=&quot;//cdn.com/foundation.min.js&quot;&gt;&lt;/script&gt;

//bad
.example {
     background: url(http://static.example.com/images/bg.jpg);
}

//good 推荐
.example {
    background: url(//static.example.com/images/bg.jpg);
}
</code></pre><h2 id="-">本地缓存</h2>
<p>在编写代码时，请注意代码对上一个版本的兼容性，特别是本地缓存(LocalStorage)中有增减字段的.</p>
<p>如有从服务器或其他非自己可控来源的数据，保存在本地缓存的，请务必定期或者使用某种行为触发对其进行刷新。</p>
<h2 id="-">登录</h2>
<p>有些APP(尤其是苹果APP)，会存在第一次登录后长期不再登录的情况，所以尽量不要在登录的成功回调里面做其他无关的操作。</p>
<h2 id="-">注释</h2>
<p>注释必不可少，但尽量编写自解释代码。</p>
<p>在文件的头部必须注明文件用途，作者，创建时间。</p>
<p>写注释时一定要注意：不要写你的代码都干了些什么，而要写你的代码为什么要这么写，背后的考量是什么。当然也可以加入所思考问题或是解决方案的链接地址。</p>
<h2 id="-">代码验证与检查</h2>
<p>可以使用JSHint检查验证你的JS代码</p>
<h1 id="js-">JS规范</h1>
<h2 id="-">类型</h2>
<ul>
<li><p><strong>原始值</strong>: 存取直接作用于它自身。</p>
<ul>
<li><p>string</p>
</li>
<li><p>number</p>
</li>
<li><p>boolean</p>
</li>
<li><p>null</p>
</li>
<li><p>undefined</p>
</li>
</ul>
<pre><code>var foo = 1;
var bar = foo;

bar = 9;

console.log(foo, bar); // =&gt; 1, 9
</code></pre></li>
<li><p><strong>复杂类型</strong>: 存取时作用于它自身值的引用</p>
<ul>
<li><p>object</p>
</li>
<li><p>array</p>
</li>
<li><p>function</p>
</li>
</ul>
<pre><code>var foo = [1, 2];
var bar = foo;

bar[0] = 9;

console.log(foo[0], bar[0]); // =&gt; 9, 9
</code></pre></li>
</ul>
<h2 id="-">对象</h2>
<ul>
<li><p>使用直接量创建对象。</p>
<pre><code>  // bad
  var item = new Object();

  // good
  var item = {};
</code></pre></li>
<li><p>不要使用保留字作为键名，它们在 IE8 下不工作。</p>
<pre><code>  // bad
  var superman = {
      default: { clark: &#39;kent&#39; },
      private: true
  };

  // good 推荐
  var superman = {
      defaults: { clark: &#39;kent&#39; },
      hidden: true
  };
</code></pre></li>
</ul>
<h2 id="-">数组</h2>
<ul>
<li><p>使用直接量创建数组。</p>
<pre><code>  // bad
  var items = new Array();

  // good 推荐
  var items = [];
</code></pre><p>  使用 Array 构造器很容易因为传参不恰当导致错误.为了避免这些歧义, 我们应该使用更易读的直接量来声明.</p>
</li>
<li><p>向数组增加元素时使用 Array#push 来替代直接赋值。</p>
<pre><code>  var someStack = [];

  // bad
  someStack[someStack.length] = &#39;abracadabra&#39;;

  // good 推荐
  someStack.push(&#39;abracadabra&#39;);
</code></pre></li>
<li><p>当你需要深拷贝数组时，使用 Array#slice。</p>
<pre><code>  var len = items.length;
  var itemsCopy = [];
  var i;

  // bad
  for (i = 0; i &lt; len; i++) {
      itemsCopy[i] = items[i];
  }

  // good 推荐
  itemsCopy = items.slice();
</code></pre></li>
<li><p>使用 Array#slice 将类数组对象转换成数组。</p>
<pre><code>  function trigger() {
      var args = Array.prototype.slice.call(arguments);
      ...
  }
</code></pre></li>
<li><p>永远不要使用 Array 作为 map/hash/associative 数组.</p>
<p>  数组中不允许使用非整型作为索引值, 所以也就不允许用关联数组. 而取代它使用 Object 来表示 map/hash 对象. Array 仅仅是扩展自 Object (类似于其他 JS 中的对象, 就像 Date, RegExp 和 String)一样来使用.</p>
</li>
</ul>
<h2 id="-">字符串</h2>
<ul>
<li><p>使用 &#39; 优于 &quot;</p>
<p>  单引号 (&#39;) 优于双引号 (&quot;). 当你创建一个包含 HTML 代码的字符串时就知道它的好处了.</p>
<pre><code>  var msg = &#39;This is some HTML&#39;;
</code></pre></li>
</ul>
<ul>
<li><p>超过 80 个字符的字符串应该使用连接符写成多行。注：若过度使用，通过连接符连接的长字符串可能会影响性能。</p>
<pre><code>  // bad
  var errorMessage = &#39;This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.&#39;;

  // bad
  var errorMessage = &#39;This is a super long error that was thrown because \
      of Batman. When you stop to think about how Batman had anything to do \
      with this, you would get nowhere \
      fast.&#39;;

  // good
  var errorMessage = &#39;This is a super long error that was thrown because &#39; +
      &#39;of Batman. When you stop to think about how Batman had anything to do &#39; +
      &#39;with this, you would get nowhere fast.&#39;;
</code></pre><p>  在编译时, 不能忽略行起始位置的空白字符; &quot;\&quot; 后的空白字符会产生奇怪的错误; 虽然大多数脚本引擎支持这种写法, 但它不是 ECMAScript 的标准规范.</p>
</li>
<li><p>join()来创建字符串</p>
<pre><code>  //bad
  function listHtml(items) {   
      var html = &#39;&lt;div class=&quot;foo&quot;&gt;&#39;;   
      for (var i = 0; i &lt; items.length; ++i) {     
          if (i &gt; 0) {       
              html += &#39;, &#39;;     
          }     
          html += itemHtml(items[i]);   
      }           
      html += &#39;&lt;/div&gt;&#39;; 

      return html; 
  }

  //good 推荐
  function listHtml(items) {   
      var html = [];   
      for (var i = 0; i &lt; items.length; ++i) {     
          html[i] = itemHtml(items[i]);   
      }

      return &#39;&lt;div class=&quot;foo&quot;&gt;&#39; + html.join(&#39;, &#39;) + &#39;&lt;/div&gt;&#39;;
  }
</code></pre><p>你也可以是用数组作为字符串构造器, 然后通过 myArray.join(&#39;&#39;) 转换成字符串. <strong>不过由于赋值操作快于数组的 push(), 所以尽量使用赋值操作</strong>.</p>
</li>
</ul>
<h2 id="-">函数</h2>
<ul>
<li><p>不要在块内声明一个函数.</p>
<p>  虽然很多JS引擎都支持块内声明函数, 但它不属于 ECMAScript 规范 (见 ECMA-262, 第13和14条). 各个浏览器糟糕的实现相互不兼容, 有些也与未来 ECMAScript 草案相违背. ECMAScript 只允许在脚本的根语句或函数中声明函数.</p>
<p>  如果确实需要在块中定义函数, 建议使用函数表达式来初始化变量.</p>
<pre><code>  //bad 申明函数
  if (x) {   
      function foo() {
      } 
  }

  //good 匿名函数表达式 推荐
  if (x) {   
      var foo = function() {
      } 
  }
</code></pre></li>
<li><p>IIFE（立即调用的函数表达式）</p>
<p>  总是将代码包裹成一个 IIFE(Immediately-Invoked Function Expression)，用以创建独立隔绝的定义域。这一举措可防止全局命名空间被污染。</p>
<p>  IIFE 还可确保你的代码不会轻易被其它全局命名空间里的代码所修改（i.e. 第三方库，window 引用，被覆盖的未定义的关键字等等）。</p>
<pre><code>  //bad
  var x = 10, y = 100;

  console.log(window.x + &#39; &#39; + window.y);

  //good 推荐
  (function(log, w, undefined){
      var x = 10,
      y = 100;

       // Will output &#39;true true&#39;
      log((w.x === undefined) + &#39; &#39; + (w.y === undefined));
  }(window.console.log, window));
</code></pre></li>
</ul>
<h2 id="-">变量</h2>
<p>声明变量必须加上 var 关键字.</p>
<p>当你没有写 var, 变量就会暴露在全局上下文中, 这样很可能会和现有变量冲突. 另外, 如果没有加上, 很难明确该变量的作用域是什么, 变量也很可能像在局部作用域中, 很轻易地泄漏到 Document 或者 Window 中, 所以务必用 var 去声明变量.</p>
<p>使用驼峰式命名对象、函数和实例。使用帕斯卡式命名构造函数或类。使用下划线 _开头命名私有属性</p>
<h2 id="-">常量</h2>
<p>常量的形式如:NAMES_LIKE_THIS, 即使用大写字符, 并用下划线分隔.请永远不要使用 const 关键词.    </p>
<h2 id="-">闭包</h2>
<p>可以使用, 但需小心使用.闭包也许是JS中最有用的特性了. <a href="http://jibbering.com/faq/faq_notes/closures.html">这里有一份比较好的介绍闭包原理的文档</a>.</p>
<p>有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 DOM 元素附加闭包时, 很可能会产生循环引用, 进一步导致内存泄漏. 比如下面的代码:</p>
<pre><code>function foo(element, a, b) {   
    element.onclick = function() {
        /* uses a and b */ 
    }; 
}
</code></pre><p>这里, 即使没有使用 element, 闭包也保留了 element, a 和 b 的引用, . 由于 element 也保留了对闭包的引用, 这就产生了循环引用, 这就不能被 GC 回收. 这种情况下, 可将代码重构为:</p>
<pre><code>function foo(element, a, b) {   
    element.onclick = bar(a, b); 
}  

function bar(a, b) {   
    return function() {
        /* uses a and b */ 
    } 
}
</code></pre><h2 id="prototype">prototype</h2>
<p>非必要情况，不要去扩展内置对象的prototype</p>
<p>如 Object.prototype 和 Array.prototype 的原型. 而修改内置对象, 如 Function.prototype 的原型, 虽然少危险些, 但仍会导致调试时的诡异现象. 所以也要避免修改其原型.</p>
<h2 id="-">&amp;&amp; ||</h2>
<p>二元布尔操作符是可短路的, 只有在必要时才会计算到最后一项.</p>
<p>&quot;||&quot; 被称作为 &#39;default&#39; 操作符, 因为可以这样:</p>
<pre><code>function foo(opt_win) {   
    var win;   
    if (opt_win) {     
        win = opt_win;   
    } else {     
        win = window;   
    }   
}
</code></pre><p>你可以使用它来简化上面的代码:</p>
<pre><code>function foo(opt_win) {   
    var win = opt_win || window;   
}
</code></pre><p>&quot;&amp;&amp;&quot; 也可简短代码.比如:</p>
<pre><code>if (node) {   
    if (node.kids) {     
        if (node.kids[index]) {       
            foo(node.kids[index]);     
        }   
    } 
}
</code></pre><p>你可以像这样来使用:</p>
<pre><code>if (node &amp;&amp; node.kids &amp;&amp; node.kids[index]) {   
    foo(node.kids[index]); 
}
</code></pre><p>或者:</p>
<pre><code>var kid = node &amp;&amp; node.kids &amp;&amp; node.kids[index]; 
if (kid) {  
    foo(kid);
}
</code></pre><p>不过这样就有点儿过头了:</p>
<pre><code>node &amp;&amp; node.kids &amp;&amp; node.kids[index] &amp;&amp; foo(node.kids[index]);
</code></pre><h2 id="-">条件表达式 等号</h2>
<ul>
<li><p>件表达式例如 if 语句通过抽象方法 ToBoolean 强制计算它们的表达式并且总是遵守下面的规则：</p>
<ul>
<li><strong>对象</strong> 被计算为 <strong>true</strong></li>
<li><strong>Undefined</strong> 被计算为 <strong>false</strong></li>
<li><strong>Null</strong> 被计算为 <strong>false</strong></li>
<li><strong>布尔值</strong> 被计算为 <strong>布尔的值</strong></li>
<li><strong>数字</strong> 如果是 <strong>+0</strong>、<strong>-0</strong>、<strong>0</strong> 或 <strong>NaN</strong> 被计算为 <strong>false</strong>，否则为 <strong>true</strong></li>
<li><strong>字符串</strong> 如果是空字符串 &#39;&#39; 被计算为 <strong>false</strong>，否则为 <strong>true</strong></li>
</ul>
</li>
<li><p>使用快捷方式。</p>
<pre><code>  // bad
  if (name !== &#39;&#39;) {
      // ...stuff...
  }

  // good 推荐
  if (name) {
      // ...stuff...
  }

  // bad 
  if (collection.length &gt; 0) {
       // ...stuff...
  }

  // good 推荐
  if (collection.length) {
      // ...stuff...
  }
</code></pre></li>
<li><p>优先使用 === 和 !== 而不是 == 和 !=</p>
<p>  如果你明确知道变量类型，在进行比较时，应该使用===进行精准比较</p>
</li>
</ul>
<h2 id="-">条件三元运算符(？：)</h2>
<p>三元操作符用于替代下面的代码</p>
<pre><code>if (val != 0) {
    return foo();
} else {
    return bar();
}
</code></pre><p>你可以写成:</p>
<pre><code>return val ? foo() : bar();
</code></pre><p>在生成 HTML 代码时也是很有用的:</p>
<pre><code>var html = &#39;&lt;input type=&quot;checkbox&quot;&#39; 
        + (isChecked ? &#39; checked&#39; : &#39;&#39; )
        + (isEnabled ? &#39;&#39; : &#39; disabled’)
        +’ name=&quot;foo&quot;&gt;&#39;;
</code></pre><h2 id="-">逗号</h2>
<p>额外的行末逗号：不需要。严格禁止在数组或者对象直接量后面留有多余的逗号如：</p>
<pre><code>[&quot;alice&#39;,&#39;john&#39;,&#39;bob&#39;,]
</code></pre><p>且额外的行末逗号会在 IE6/7 和 IE9 怪异模式下引起问题。同样，多余的逗号在某些 ES3 的实现里会增加数组的长度。</p>
<h2 id="-">分号</h2>
<p>总是使用分号.</p>
<p>如果仅依靠语句间的隐式分隔, 有时会很麻烦. 你自己更能清楚哪里是语句的起止.</p>
<p>而且有些情况下, 漏掉分号会很危险:</p>
<pre><code>1.  MyClass.prototype.myMethod = function() {
        return 42; 
    }  // No semicolon here. 

    (function() {   
    // Some initialization code wrapped in a function to create a scope for locals. 
    })(); 

2.  // Trying to do one thing on Internet Explorer and another on Firefox. 
    // I know you&#39;d never write code like this, but throw me a bone. 
    var x = {
        &#39;i&#39;: 1,
        &#39;j&#39;: 2
    }  // No semicolon here.

    [normalVersion, ffVersion][isIE]();   

3.  var THINGS_TO_EAT = [apples, oysters, sprayOnCheese]  // No semicolon here.  

    // conditional execution a la bash
    -1 == resultOfOperation() || die();
</code></pre><ul>
<li><p>这段代码会发生些什么诡异事呢?</p>
<p>  1.报 JavaScript 错误. 例子1上的语句会解释成, 一个函数带一匿名函数作为参数而被调用, 返回42后, 又一次被&quot;调用&quot;, 这就导致了错误.</p>
<p>  2.例子2中, 你很可能会在运行时遇到 &#39;no such property in undefined&#39; 错误, 原因是代码试图这样 x[ffVersion][isIE]() 执行.</p>
<p>  3.当 resultOfOperation() 返回非 NaN 时, 就会调用die, 其结果也会赋给 THINGS_TO_EAT.</p>
</li>
<li><p>为什么</p>
<p>  JavaScript 的语句以分号作为结束符, 除非可以非常准确推断某结束位置才会省略分号. 上面的几个例子产出错误, 均是在语句中声明了函数/对象/数组直接量, 但闭括号( &#39;}&#39; 或 &#39;]&#39; )并不足以表示该语句的结束. 在 JavaScript 中, 只有当语句后的下一个符号是后缀或括号运算符时, 才会认为该语句的结束.</p>
<p>  遗漏分号有时会出现很奇怪的结果, 所以确保语句以分号结束.</p>
</li>
</ul>
<h2 id="eval-">eval()</h2>
<p>只用于解析序列化串 (如: 解析 RPC 响应)</p>
<p>eval() 会让程序执行的比较混乱, 当 eval() 里面包含用户输入的话就更加危险. 可以用其他更佳的, 更清晰, 更安全的方式写你的代码, 所以一般情况下请不要使用 eval(). 当碰到一些需要解析序列化串的情况下(如, 计算 RPC 响应), 使用 eval 很容易实现.</p>
<p>解析序列化串是指将字节流转换成内存中的数据结构. 比如, 你可能会将一个对象输出成文件形式:</p>
<pre><code>users = [
        {     
            name: &#39;Eric&#39;,    
            id: 37824,     
            email: &#39;jellyvore@myway.com&#39;   
       },   
       {     
            name: &#39;xtof&#39;,     
            id: 31337,     
            email: &#39;b4d455h4x0r@google.com&#39;   
       },   
       ... 
   ];
</code></pre><p>很简单地调用 eval 后, 把表示成文件的数据读取回内存中.</p>
<p>类似的, eval() 对 RPC 响应值进行解码. 例如, 你在使用 XMLHttpRequest 发出一个 RPC 请求后, 通过 eval () 将服务端的响应文本转成 JavaScript 对象:</p>
<pre><code>var userOnline = false; 
var user = &#39;nusrat&#39;; 

var xmlhttp = new XMLHttpRequest(); 
xmlhttp.open(&#39;GET&#39;, &#39;http://chat.google.com/isUserOnline?user=&#39; + user, false); 
xmlhttp.send(&#39;&#39;); //Server returns: // userOnline = true;

if (xmlhttp.status == 200) {
    eval(xmlhttp.responseText); 
} // userOnline is now true.
</code></pre><h2 id="for-in-">for-in 循环</h2>
<p>只用于 object/map/hash 的遍历</p>
<p>对 Array 用 for-in 循环有时会出错. 因为它并不是从 0 到 length - 1 进行遍历, 而是所有出现在对象及其原型链的键值. 下面就是一些失败的使用案例:</p>
<pre><code>function printArray(arr) {   
    for (var key in arr) {     
        print(arr[key]);   
    } 
}  
printArray([0,1,2,3]);  // This works.  
var a = new Array(10); 
printArray(a);  // This is wrong.  
a = document.getElementsByTagName(&#39;*&#39;); 
printArray(a);  // This is wrong.  

a = [0,1,2,3]; 
a.buhu = &#39;wine&#39;; 
printArray(a);  // This is wrong again.  

a = new Array; 
a[3] = 3; 
printArray(a);  // This is wrong again.
</code></pre><p>而遍历数组通常用最普通的 for 循环</p>
<pre><code>function printArray(arr) {  
    var l = arr.length;   
    for (var i = 0; i &lt; l; i++) {
        print(arr[i]);   
    }
}
</code></pre><h2 id="-tostring-">自定义 toString() 方法</h2>
<p>应该总是成功调用且不要抛异常.</p>
<p>可自定义 toString() 方法, 但确保你的实现方法满足: (1) 总是成功 (2) 没有其他负面影响. </p>
<p>如果不满足这两个条件, 那么可能会导致严重的问题, 比如, 如果 toString() 调用了包含 assert 的函数, assert 输出导致失败的对象, 这在 toString() 也会被调用.</p>
<h2 id="-node-list">遍历Node List</h2>
<p>Node lists 是通过给节点迭代器加一个过滤器来实现的. 这表示获取他的属性, 如 length 的时间复杂度为 O(n), 通过 length 来遍历整个列表需要 O(n^2).</p>
<pre><code>var paragraphs = document.getElementsByTagName(&#39;p&#39;); 
for (var i = 0; i &lt; paragraphs.length; i++) {   
    doSomething(paragraphs[i]); 
}
</code></pre><p>这样做会更好:</p>
<pre><code>var paragraphs = document.getElementsByTagName(&#39;p&#39;); 
for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) {   
    doSomething(paragraph); 
}
</code></pre><p>这种方法对所有的 collections 和数组(只要数组不包含 falsy 值) 都适用.</p>
<p>在上面的例子中, 也可以通过 firstChild 和 nextSibling 来遍历孩子节点.</p>
<pre><code>var parentNode = document.getElementById(&#39;foo&#39;); 
for (var child = parentNode.firstChild; child; child = child.nextSibling) {   
    doSomething(child); 
}
</code></pre><h2 id="-">命名</h2>
<ul>
<li><p>通常使用</p>
<p>  functionNamesLikeThis</p>
<p>  variableNamesLikeThis </p>
<p>  ClassNamesLikeThis</p>
<p>  EnumNamesLikeThis</p>
<p>  methodNamesLikeThis</p>
<p>  SYMBOLIC_CONSTANTS_LIKE_THIS</p>
<p>  _privateVariableNamesLikeThis</p>
<p>  _privateMethodNamesLikeThis</p>
</li>
<li><p>属性和方法</p>
<p>  文件或类中的 私有 属性, 变量和方法名应该以下划线 &quot;_&quot; 开头.</p>
<p>  保护属性, 变量和方法名不需要下划线开头, 和公共变量名一样.</p>
</li>
<li><p>方法和函数参数</p>
<p>  可选参数以 opt_ 开头.</p>
<p>  函数的参数个数不固定时, 应该添加最后一个参数 var_args 为参数的个数. 你也可以不设置 var_args而取代使用 arguments. </p>
</li>
</ul>
<h2 id="-">编码风格</h2>
<p>{}统一使用如下两种风格</p>
<pre><code>function func()
{
}
</code></pre><p>or</p>
<pre><code>function func() {
}
</code></pre><h1 id="html-css-">HTML/CSS 规范</h1>
<h2 id="-html5-">推荐使用 HTML5 的文档类型申明：</h2>
<pre><code>&lt;!DOCTYPE html&gt;
</code></pre><p>（建议使用 text/html 格式的 HTML。避免使用 XHTML。XHTML 以及它的属性，比如 application/xhtml+xml 在浏览器中的应用支持与优化空间都十分有限）。</p>
<h2 id="-">不要将无内容元素的标签闭合</h2>
<pre><code>//bad
&lt;br/&gt;

//good 推荐
&lt;br&gt;
</code></pre><h2 id="-">脚本加载</h2>
<p>加载脚本的代码放在DOM结构的末尾</p>
<pre><code>//bad
&lt;html&gt;
    &lt;head&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;main.css&quot;&gt;
        &lt;script src=&quot;main.js&quot; async&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body&gt;
           &lt;!-- body goes here --&gt;
    &lt;/body&gt;
&lt;/html&gt;

//good 推荐
&lt;html&gt;
    &lt;head&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;main.css&quot;&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;!-- body goes here --&gt;
    &lt;/body&gt;
    &lt;script src=&quot;main.js&quot; async&gt;&lt;/script&gt;
&lt;/html&gt;
</code></pre><h2 id="-">使用语义化的标签</h2>
<p>尽量使用语义化的标签，例如p，h1，a等，在支持html5的环境中，尽量使用h5的语义化标签，例如header, footer, main, section, nav等</p>
<h2 id="-">使用模板加载数据</h2>
<p>如有使用模板加载对象，请对代码进行try,catch.</p>
<h1 id="butterfly-">butterfly规范</h1>
<h2 id="-html-">页面的HTML结构</h2>
<pre><code>&lt;div id=&quot;rootName&quot; data-view=&quot;pathToJS&quot;&gt;
    // 1：本View相关的CSS定义
    &lt;style&gt;
        // 所有CSS定义之前，必须添加#rootName以限定CSS仅对本View生效
        #rootName .viewCSSName {
        }
    &lt;/style&gt;

    // 2：本View相关Template定义
    &lt;script id=&quot;templateName&quot; type=&quot;text/x-underscore-template&quot;&gt;
        …
    &lt;/script&gt;
    …
    &lt;script id=&quot;templateName&quot; type=&quot;text/x-underscore-template&quot;&gt;
        …
    &lt;/script&gt;

    // 3：本View的Header定义
    &lt;header id=&quot;nav-bar&quot; class=&quot;bar bar-nav blue-bar&quot; navLeft=&#39;{&quot;hide&quot;:&quot;true&quot;}&#39; navTitle=&#39;&quot;这是标题&quot;&#39; navRight=&#39;{&quot;hide&quot;:&quot;true&quot;}&#39;&gt;
    &lt;/header&gt;

    // 4：本View的UI定义,class必须指定为content
    &lt;div class=&quot;content&quot;&gt;
        …
    &lt;/div&gt;
&lt;/div&gt;
</code></pre><ul>
<li><p>说明:</p>
<p>  1：页面HTML文件充当UI结构和布局，充当View角色    </p>
<p>  2：data-view中pathToJS指定了该View对应的JS文件，建立View-Controller的关系 </p>
<p>  3：Template定义块和Header定义块为可选</p>
<p>  4：View的实际内容放在UI定义块里面，内容中UI位置均相对于.content div设置，不能依赖于.content div以外的任何节点</p>
</li>
</ul>
<h2 id="-js-">页面的JS文件</h2>
<pre><code>define([
        &quot;dependentClassBase&quot;, 
        &quot;dependentModel0&quot;, 
        &quot;dependentModel1&quot;,
         …
    ],
    function(ClassBase, Model0, Model1, …) {    
        // 定义内部常量(Inner Variable)和内部函数(Inner Function)
        var CONSTANT_VARIBALE = &quot;THIS IS A CONSTANT STRING&quot;;
        var innerFunction = function() {
        }            

        // 定义类(Class)
        var Class = {};

        // 类构造函数
        Class.constructor = function(options) {
            // 调用基类的构造函数，构造基类
            ClassBase.prototype.contructor.call(this, options);

            // 构造自己
            // 定义类成员变量
            this._memberVariable = xxx;
        }

        // 定义类public成员函数
        Class.publicMemberFunction = function() {
        }
        ……

        // 定义类private、protected成员函数
        Class._privateMemberFunction = function() {
        }

        Class._protectedMemberFunction = function() {
        }

        // 让Class类继承于ClassBase，导出Class
        return ClassBase.extend(Class);        
    });
</code></pre><ul>
<li><p>说明</p>
<p>  1：define相关语法参加require.js文档</p>
<p>  2：页面的JS文件充当Controller，该页面的逻辑在此实现，通过HTML中data-view和HTML建立绑定关系</p>
<p>  3：仅仅在该类中使用的常量和函数优先于类定义</p>
<p>  4：该类的成员变量，应该在constructor中定义和初始化，并且使用_memberVariable的格式命名</p>
<p>  5：优先定义该类的public成员函数，然后定义private、protected成员函数，并且private、protected成员函数使用_privateMemberFunction命名（参见命名规则）</p>
<p>  6：private、protected的成员函数和成员变量对外应该是不可见的，外部不应该调用和使用具有_前缀的函数和变量（参见命名规则）</p>
</li>
</ul>
<h2 id="-this-">保存成员函数的this对象</h2>
<p>使用butterfly框架，在稍微复杂的成员函数实现中，可以在函数开头用：</p>
<pre><code>var  me = this;
</code></pre><p>保存好成员函数的this对象，便于其它内嵌函数使用。</p>
<h2 id="-">变色龙后台</h2>
<p>使用变色龙后台发布的APP，添加一个新的模块(在app目录下新建了一个子目录)后,请务必添加一个package.json文件，格式请参照其他模块</p>
<h2 id="-">事件的绑定</h2>
<p>使用butterfly框架，一些重要事件的绑定，尽量放在render或onShow中其它代码的前面</p>
<h1 id="parting-words">Parting Words</h1>
<ul>
<li><p>保持一致性</p>
<p>  当你在编辑代码之前, 先花一些时间查看一下现有代码的风格. 如果他们给算术运算符添加了空格, 你也应该添加. 如果他们的注释使用一个个星号盒子, 那么也请你使用这种方式.</p>
<p>  代码风格中一个关键点是整理一份常用词汇表, 开发者认同它并且遵循, 这样在代码中就能统一表述. 我们在这提出了一些全局上的风格规则, 但也要考虑自身情况形成自己的代码风格. 但如果你添加的代码和现有的代码有很大的区别, 这就让阅读者感到很不和谐. 所以, 避免这种情况的发生.</p>
</li>
</ul>

          	</article>
        </div>
		</div>
  </body>
</html>
<script type="text/javascript" src="toc/js/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="toc/js/jquery.ztree.all-3.5.min.js"></script>
<script type="text/javascript" src="toc/js/ztree_toc.js"></script>
<script type="text/javascript" src="toc_conf.js"></script>

<SCRIPT type="text/javascript" >
<!--
$(document).ready(function(){
    var css_conf = eval(markdown_panel_style);
    $('#readme').css(css_conf)
    
    var conf = eval(jquery_ztree_toc_opts);
		$('#tree').ztree_toc(conf);
});
//-->
</SCRIPT>